package com.yangdada.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yangdada.dto.*;
import com.yangdada.entity.Blog;
import com.yangdada.enums.DateHourSearchEnum;
import com.yangdada.service.IBlogService;
import com.yangdada.service.facade.Constants;
import com.yangdada.service.facade.DateFacade;
import com.yangdada.utils.DateReplenishUtil;
import com.yangdada.utils.Result;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ykl
 * @since 2022-08-06
 */
@RestController
@RequestMapping("/blog")
public class BlogController {

    @Resource
    private DateFacade facade;
    @Resource
    private IBlogService blogService;

    /**
     * 通过多条sql查询出的数据绑定到一个实体类中并通过一个接口返回
     * @param publicRequestDTO
     * @return
     */
    @PostMapping("/twoData")
    public Result getTwoData(@RequestBody PublicRequestDTO publicRequestDTO) throws InterruptedException {
//        //拿到实体类数据
//        TwoDataTestResponseDTO twoDataTestResponseData = blogService.getTwoDataTestResponseData(publicRequestDTO);
//        map.put("twoDataTestResponseData",twoDataTestResponseData);
//        //拿到按照时间进行分组的list集合数据
//        List<PublicDataDTO> twoDataTest = blogService.getTwoDataTest(publicRequestDTO);
//        //将list转换为map，补全数据库中空缺日期的数据
//        Map<String, PublicDataDTO> collect = twoDataTest.stream().collect(Collectors.toMap(PublicDataDTO::getDate, Function.identity(), (k, v) -> k));
//        try {
//            //通过实体类中的数据进行补全
//            twoDataTest = DateReplenishUtil.dateReplenish(collect, new PublicDataDTO(), publicRequestDTO.getStartDate(), publicRequestDTO.getEndDate());
//            twoDataTest = twoDataTest.stream().sorted((k, v) -> k.getDate().compareTo(v.getDate())).collect(Collectors.toList());
//            map.put("twoDataTest",twoDataTest);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        checkRequestParam(publicRequestDTO);
        PublicRequestDTO publicRequestDTO1 = setGroupSearchInfo(publicRequestDTO);
        Map<String, Object> twoData = facade.getTwoData(publicRequestDTO1);

        return Result.ok(twoData);
    }

    @PostMapping("/twoData2")
    public Result getTwoDataMerge(@RequestBody PublicRequestDTO publicRequestDTO) throws InterruptedException {
        checkRequestParam(publicRequestDTO);
        PublicRequestDTO publicRequestDTO1 = setGroupSearchInfo(publicRequestDTO);
        TwoDataResponseDTO twoData = blogService.getTwoData(publicRequestDTO1);
        List<TwoDataMergeResponseDTO> helpMeSaleOrderAxis = twoData.getTwoDataMergeResponseDTOList();
        Map<String, TwoDataMergeResponseDTO> axisVoMap = helpMeSaleOrderAxis.stream().collect(Collectors.toMap(TwoDataMergeResponseDTO::getDate, Function.identity(), (k, v) -> k));
        List<TwoDataMergeResponseDTO> fillAxisVoList;
        // 小时维度查看
        if (DateHourSearchEnum.HOUR_SEARCH.getCode().equals(publicRequestDTO.getHourFlag())) {
            fillAxisVoList = buildSummaryAxisByHour(axisVoMap, new TwoDataMergeResponseDTO(),"orderData");
        } else {
            fillAxisVoList = buildSummaryAxisByDate(axisVoMap, publicRequestDTO.getStartDate(), publicRequestDTO.getEndDate(), new TwoDataMergeResponseDTO(),"orderData");
        }
        helpMeSaleOrderAxis.addAll(fillAxisVoList);
        List<TwoDataMergeResponseDTO> sortAxisVo = helpMeSaleOrderAxis.stream().
                sorted(Comparator.comparing(TwoDataMergeResponseDTO::getDate)).collect(Collectors.toList());
        twoData.setTwoDataMergeResponseDTOList(sortAxisVo);
        return Result.ok(twoData);
    }

    private <T> List<T> buildSummaryAxisByHour(Map<String, T> axisMap, T t,String type) {
        List<T> axisList = new ArrayList<T>();
        for (int hour = Constants.HOUR_MIX; hour < Constants.HOUR_MAX; hour++) {
            String dayStr = String.format("%02d", hour);
            T w = axisMap.get(dayStr);
            if (Objects.isNull(w)) {
                fillSummaryAxisDate(t, axisList, dayStr,type);
            }
        }
        return axisList;
    }

    private <T> List<T> buildSummaryAxisByDate(Map<String, T> axisMap, String startDateStr, String endDateStr, T t,String type) {
        List<T> axisList = new ArrayList<T>();
        // 开始日期
        Date startDate = com.yangdada.utils.DateUtil.getStringToDate(startDateStr, com.yangdada.utils.DateUtil.DATE_FORMAT);
        // 结束日期
        Date endDate = com.yangdada.utils.DateUtil.getStringToDate(endDateStr, com.yangdada.utils.DateUtil.DATE_FORMAT);
        while (startDate.compareTo(endDate) <= 0) {
            String dateStr = com.yangdada.utils.DateUtil.dateToStr(startDate, com.yangdada.utils.DateUtil.DATE_FORMAT);
            if (Objects.isNull(axisMap.get(dateStr))) {
                fillSummaryAxisDate(t, axisList, dateStr,type);
            }
            startDate = com.yangdada.utils.DateUtil.addDate(startDate, 1);
        }
        return axisList;
    }

    private <T> void fillSummaryAxisDate(T t, List<T> axisList, String dateStr, String type) {
            if (type.equals("orderData")){
                if (t instanceof TwoDataMergeResponseDTO) {
                    TwoDataMergeResponseDTO helpMeSaleDateVO = new TwoDataMergeResponseDTO();
                    helpMeSaleDateVO.setDate(dateStr);
                    axisList.add((T) helpMeSaleDateVO);
                } else if (t instanceof TwoDataMergeResponseDTO) {
                    TwoDataMergeResponseDTO helpMeSaleDateVO = new TwoDataMergeResponseDTO();
                    helpMeSaleDateVO.setDate(dateStr);
                    axisList.add((T) helpMeSaleDateVO);
                }
            }
    }

    private void checkRequestParam(PublicRequestDTO publicRequestDTO) {
        Assert.notNull(publicRequestDTO.getStartDate(), "开始日期不能为空");
        Assert.notNull(publicRequestDTO.getEndDate(),"结束日期不能为空");
    }

    private PublicRequestDTO setGroupSearchInfo(PublicRequestDTO publicRequestDTO) {

        publicRequestDTO.setStartDate(publicRequestDTO.getStartDate().concat(Constants.SEARCH_PARAMS_TIME_MIN));
        publicRequestDTO.setEndDate(publicRequestDTO.getEndDate().concat(Constants.SEARCH_PARAMS_TIME_MAX));
        return publicRequestDTO;
    }

}
